using System;
using System.Collections.Generic;
using System.Text;
using Csla;
using System.Data;
using Active.Core.DB;
using Csla.Data;
using NBearLite;

namespace Active.Core
{
    [Serializable()]
    public class CustomerList :
      ReadOnlyListBase<CustomerList, CustomerInfo>
    {
        #region Paging

        private int _totalRecordsCount;
        public int TotalRecordsCount
        {
            get
            {
                return _totalRecordsCount;
            }
        }

        private int _pageNo;
        public int PageNo
        {
            get
            {
                return _pageNo;
            }
        }

        private int _pageSize;
        public int PageSize
        {
            get
            {
                return _pageSize;
            }
        }

        private bool _allowPaging = false;
        public bool AllowPaging
        {
            get
            {
                return _allowPaging;
            }
        }

        #endregion

        #region Authorization Rules

        /// <summary>
        /// Determines whether this instance [can get object].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance [can get object]; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanGetObject()
        {
            // TODO: customize to check user role
            //return ApplicationContext.User.IsInRole("");
            return true;
        }

        #endregion

        #region Factory Methods

        /// <summary>
        /// Gets the Customer list.
        /// </summary>
        /// <returns></returns>
        public static CustomerList GetCustomerList()
        {
            return DataPortal.Fetch<CustomerList>(new Criteria());
        }

        public static CustomerList GetCustomerList(int pageNo, int pageSize)
        {
            return DataPortal.Fetch<CustomerList>(new Criteria(pageNo, pageSize));
        }

        public static CustomerList GetCustomerList(string nameToSearch, int pageNo, int pageSize)
        {
            return DataPortal.Fetch<CustomerList>(new Criteria(nameToSearch, pageNo, pageSize));
        }

        private CustomerList()
        { /* require use of factory methods */ }

        #endregion

        #region Data Access

        [Serializable()]
        private class Criteria
        {
            private string _nameToSearch;
            public string NameToSearch
            {
                get { return _nameToSearch; }
            }

            private int _pageNo;
            public int PageNo
            {
                get
                {
                    return _pageNo;
                }
            }

            private int _pageSize;
            public int PageSize
            {
                get
                {
                    return _pageSize;
                }
            }

            private bool _allowPaging = false;
            public bool AllowPaging
            {
                get
                {
                    return _allowPaging;
                }
            }
            public Criteria()
            {
            }

            public Criteria(int pageNo, int pageSize)
            {
                _pageNo = pageNo;
                _pageSize = pageSize;
                _allowPaging = true;
            }

            public Criteria(string nameToSearch, int pageNo, int pageSize)
            {
                _nameToSearch = nameToSearch;
                _pageNo = pageNo;
                _pageSize = pageSize;
                _allowPaging = true;
            }
        }

        private void DataPortal_Fetch(Criteria criteria)
        {
            RaiseListChangedEvents = false;
            IsReadOnly = false;
            NBearLite.SelectSqlSection select =
                DataService.DBService.Select(Tables.Customers,
                Tables.Customers.Id, Tables.Customers.Name, Tables.Customers.DealTimes);
            NBearLite.WhereClip where = NBearLite.WhereClip.All;
            if (!string.IsNullOrEmpty(criteria.NameToSearch))
            {
                where.And(Tables.Customers.Name.Contains(criteria.NameToSearch));
            }
            if (criteria.AllowPaging)
            {
                select.SetSelectRange(criteria.PageSize,
                    (criteria.PageNo - 1) * criteria.PageSize, Tables.Customers.Id);
                _allowPaging = true;
                _pageNo = criteria.PageNo;
                _pageSize = criteria.PageSize;
            }
            select.Where(where);
            select.OrderBy(Tables.Customers.DealTimes.Desc);
            using (SafeDataReader dr = new SafeDataReader(select.ToDataReader()))
            {
                while (dr.Read())
                {
                    Add(CustomerInfo.GetCustomerInfo(dr));
                }
            }
            if (_allowPaging)
            {
                _totalRecordsCount = (int)DataService.DBService.Select(Tables.Customers,
                    Tables.Customers.Id.Count()).Where(where).ToScalar();
            }
            else
            {
                _totalRecordsCount = this.Count;
            }
            IsReadOnly = true;
            RaiseListChangedEvents = true;
        }

        #endregion
    }
}

